package avicit.bdp.dms.approval.service;

import avicit.bdp.approval.api.impl.MetadataApprovalApi;
import avicit.bdp.approval.api.impl.QualityApprovalApi;
import avicit.bdp.approval.api.impl.StandardApprovalApi;
import avicit.bdp.common.base.BaseService;
import avicit.bdp.common.dto.approval.ApprovalDTO;
import avicit.bdp.approval.api.ApprovalType;
import avicit.bdp.common.utils.BdpLogUtil;
import avicit.bdp.core.constant.Constants;
import avicit.bdp.dms.approval.dao.ApprovalDAO;
import avicit.bdp.dms.approval.dto.ApprovalHistoryDTO;
import avicit.bdp.dms.approval.utils.enums.ApprovalResultType;
import avicit.bdp.core.enums.ApprovalState;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.commons.utils.ComUtil;
import avicit.platform6.commons.utils.PojoUtil;
import avicit.platform6.core.context.ThreadContextHelper;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.properties.PlatformConstant;
import avicit.platform6.core.rest.msg.QueryRespBean;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.Page;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @金航数码科技有限责任公司
 * @作者：developer
 * @邮箱：developer@avic-digital.com
 * @创建时间： 2023-06-20
 * @类说明：ApprovalService
 * @修改记录：
 * @注意事项：
 * @主要功能：审批中心Service
 */
@Service
public class ApprovalService extends BaseService<ApprovalDAO, ApprovalDTO> {
    private static final Logger logger = LoggerFactory.getLogger(ApprovalService.class);

    @Autowired
    private ApprovalHistoryService historyService;

    @Autowired
    private ConvertColumnClient convertColumnClient;

    @Autowired
    private QualityApprovalApi qualityApprovalRpc;
    @Autowired
    private MetadataApprovalApi metadataApprovalRpc;
    @Autowired
    private StandardApprovalApi standardApprovalRpc;

    /**
     * 申请/批量申请
     * @param applyList
     * @return
     */
    @Transactional
    public boolean addApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            return true;
        }

        // step1:区分新增审批申请、更新审批申请
        List<ApprovalDTO> addApplyList = new ArrayList<>();
        List<ApprovalDTO> updateApplyList = new ArrayList<>();
        for (ApprovalDTO apply : applyList) {
            if (apply == null) {
                continue;
            }
            if (StringUtils.isAnyEmpty(apply.getBusinessId(), apply.getBusinessVersion())) {
                continue;
            }

            ApprovalDTO oldApproval = this.mapper.getApprovalByCond(apply.getBusinessId(), apply.getBusinessVersion());
            if (oldApproval == null) {
                apply.setState(ApprovalState.APPROVAL.getCode());
                addApplyList.add(apply);
            } else {
                apply.setState(ApprovalState.APPROVAL.getCode());
                apply.setId(oldApproval.getId());
                updateApplyList.add(apply);
            }
        }

        // step2:批量新增/更新
        return batchInsertApproval(addApplyList)
                && this.historyService.batchInsertApplyHistory(addApplyList, false)
                && batchUpdateApproval(updateApplyList)
                && this.historyService.batchInsertApplyHistory(updateApplyList, true);
    }

    /**
     * 删除/批量删除审批，多个id使用英文逗号隔开
     * @param id
     * @return
     */
    public Integer deleteApproval(String id) {
        if (StringUtils.isBlank(id)) {
            return 0;
        }
        for (String approvalId : Arrays.asList(id.trim().split(Constants.COMMA))) {
            // 删除审批记录
            this.deleteByPrimaryKey(approvalId);
            // 删除审批历史
            this.historyService.deleteApprovalHistoryByCond(approvalId);
        }

        return 0;
    }

    /**
     * 申请/批量更新
     * @param applyList
     * @return
     */
    @Transactional
    public boolean updateApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            logger.warn("发布/批量发布成功，更新申请为空.");
            return true;
        }

        List<ApprovalDTO> updateApplyList = new ArrayList<>();
        for (ApprovalDTO apply : applyList) {
            if (apply == null) {
                continue;
            }
            if (StringUtils.isAnyEmpty(apply.getBusinessId(), apply.getBusinessVersion())) {
                continue;
            }

            ApprovalDTO oldApproval = this.mapper.getApprovalByCond(apply.getBusinessId(), apply.getBusinessVersion());
            if (oldApproval != null) {
                apply.setId(oldApproval.getId());
                updateApplyList.add(apply);

                BdpLogUtil.log4Update(apply, oldApproval);
            }
        }

        return batchUpdateApproval(updateApplyList);
    }

    /**
     * 查询申请详情
     * @param id 申请ID
     * @return
     */
    public ApprovalDTO getApprovalDetail(String id) {
        if (StringUtils.isEmpty(id)) {
            return null;
        }

        ApprovalDTO approval = this.mapper.getApprovalDetail(id);
        valueConvert(Arrays.asList(approval));
        BdpLogUtil.log4Query(approval);
        return approval;
    }

    /**
     * 分页查询我的审批列表
     * @param type
     * @param state
     * @param startTime
     * @param endTime
     * @param keyWords
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Transactional
    public QueryRespBean<ApprovalDTO> queryApprovalList(Integer type, Integer state, String startTime, String endTime,
                                                        String keyWords, Integer pageNo, Integer pageSize) {
        QueryRespBean<ApprovalDTO> queryRespBean = new QueryRespBean<>();

        // -1表示查询全部状态
        if (state.equals(-1)) {
            state = null;
        }
        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
        Page<ApprovalDTO> queryRet = this.mapper.queryApprovalByCond(type, state, startTime, endTime, keyWords, null);
        queryRespBean.setResult(queryRet);

        // step3；转换
        valueConvert(queryRet.getResult());
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    /**
     * 分页查询我的申请列表
     * @param type
     * @param state
     * @param startTime
     * @param endTime
     * @param keyWords
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Transactional
    public QueryRespBean<ApprovalDTO> queryApplyList(Integer type, Integer state, String startTime, String endTime,
                                                     String keyWords, Integer pageNo, Integer pageSize) {
        QueryRespBean<ApprovalDTO> queryRespBean = new QueryRespBean<>();

        // -1表示查询全部状态
        if (state.equals(-1)) {
            state = null;
        }

        String loginUserId = ThreadContextHelper.getUserId() == null ? "1" : ThreadContextHelper.getUserId();
        com.github.pagehelper.PageHelper.startPage(pageNo, pageSize);
        Page<ApprovalDTO> queryRet = this.mapper.queryApprovalByCond(type, state, startTime, endTime, keyWords, loginUserId);
        queryRespBean.setResult(queryRet);

        // step3；转换
        valueConvert(queryRet.getResult());
        BdpLogUtil.log4Query(queryRespBean);
        return queryRespBean;
    }

    /**
     * 查询审批进度
     * @param id 工单ID
     * @return
     */
    public List<ApprovalHistoryDTO> getApprovalProgress(String id) {
        return this.historyService.getApprovalHistoryList(id);
    }

    /**
     * 批量处理申请
     * @param applyList
     * @return
     */
    @Transactional
    public boolean processApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            return true;
        }

        for (ApprovalDTO apply : applyList) {
            if (apply == null) {
                continue;
            }
            if (StringUtils.isEmpty(apply.getId())) {
                continue;
            }
            if (apply.getApprovalResultType() == null) {
                continue;
            }

            ApprovalDTO detail = this.getApprovalDetail(apply.getId());
            if (detail == null) {
                continue;
            }

            ApprovalState state = null;
            ApprovalResultType resultType = ApprovalResultType.getTypeByCode(apply.getApprovalResultType());
            switch (resultType) {
                case ACCESS:
                    state = ApprovalState.ACCESS;
                    break;
                case REJECT:
                    state = ApprovalState.REJECT;
                    break;
                default:
                    throw new BusinessException("审批类型只能为【0/1】，处理失败.");
            }

            // 更新审批状态、版本、发布类型、审批人、审批时间
            apply.setBusinessId(detail.getBusinessId());
            apply.setBusinessVersion(detail.getBusinessVersion());
            apply.setType(detail.getType());
            apply.setState(state.getCode());
            apply.setApprovalUserId(ThreadContextHelper.getUserId() == null ? "1" : ThreadContextHelper.getUserId());
            apply.setApprovalTime(new Date());
        }

        // 批量更新审批
        this.batchUpdateApproval(applyList);
        // 批量跟新审批记录
        this.historyService.batchInsertProcessHistory(applyList);

        // 通知业务模块审批结果
        return notifyBusinessResult(applyList);
    }

    /**
     * 撤回申请
     * @param applyList
     * @return
     */
    @Transactional
    public boolean revokeApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            return true;
        }

        for (ApprovalDTO apply : applyList) {
            if (apply == null) {
                continue;
            }
            if (StringUtils.isAnyEmpty(apply.getBusinessId(), apply.getBusinessVersion())) {
                continue;
            }

            ApprovalDTO approval = this.mapper.getApprovalByCond(apply.getBusinessId(), apply.getBusinessVersion());
            if (approval == null) {
                continue;
            }

            // 更新审批记录状态为已撤回
            apply.setId(approval.getId());
            apply.setState(ApprovalState.REVOKE.getCode());
            apply.setSubmitUserId(approval.getSubmitUserId());
        }

        // 批量更新审批/审批记录
        return this.batchUpdateApproval(applyList) && this.historyService.batchInsertRevokeHistory(applyList);
    }

    /**
     * 批量新增
     * @param applyList
     * @return
     */
    private boolean batchInsertApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            return true;
        }

        for (ApprovalDTO apply : applyList) {
            apply.setId(ComUtil.getId());

            PojoUtil.setSysProperties(apply, PlatformConstant.OpType.insert);
        }

        // 批量新增审批
        this.mapper.batchInsertApproval(applyList);

        return true;
    }

    /**
     * 批量更新
     * @param applyList
     * @return
     */
    private boolean batchUpdateApproval(List<ApprovalDTO> applyList) {
        if (CollectionUtils.isEmpty(applyList)) {
            return true;
        }

        for (ApprovalDTO apply : applyList) {
            PojoUtil.setSysProperties(apply, PlatformConstant.OpType.update);
        }

        // 批量更新审批
        this.mapper.batchUpdateApproval(applyList);

        return true;
    }

    /**
     * 通知业务模块审批结果
     * @param approvalList
     * @return
     */
    private boolean notifyBusinessResult(List<ApprovalDTO> approvalList) {
        if (CollectionUtils.isEmpty(approvalList)) {
            return true;
        }

        ApprovalDTO approval = approvalList.get(0);
        if (approval.getType() == null) {
            return true;
        }

        logger.warn("通知业务模块审批结果:\n" + JSONObject.toJSONString(approvalList));

        ApprovalType type = ApprovalType.getTypeByCode(approval.getType());
        switch (type) {
            case STANDARD:
                return standardApprovalRpc.notify(approvalList);
            case QUALITY:
                return qualityApprovalRpc.notify(approvalList);
            case METADATA:
                return metadataApprovalRpc.notify(approvalList);
            default:
                throw new RuntimeException("仅支持一下发布类型：标准、质量、元数据." );

        }
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     * @param dtoList
     */
    private void valueConvert(List<ApprovalDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }

        // 设置创建者名称
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (ApprovalDTO dto : dtoList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getCreatedBy());
            if (StringUtils.isNotEmpty(dto.getSubmitUserId())) {
                BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getSubmitUserId());
            }
            if (StringUtils.isNotEmpty(dto.getApprovalUserId())) {
                BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, dto.getApprovalUserId());
            }
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (ApprovalDTO dto : dtoList) {
                dto.setCreatedBy(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getCreatedBy()));
                dto.setSubmitUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getSubmitUserId()));
                dto.setApprovalUserName(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER, dto.getApprovalUserId()));
            }

//            /*******************打桩代码**************************/
//            for (ApprovalDTO dto : dtoList) {
//                if (dto.getCreatedBy().equals("1")) {
//                    dto.setCreatedBy("平台管理员");
//                }
//                if (StringUtils.isNotEmpty(dto.getSubmitUserId())) {
//                    if (dto.getSubmitUserId().equals("1")) {
//                        dto.setSubmitUserName("平台管理员");
//                    }
//                }
//                if (StringUtils.isNotEmpty(dto.getApprovalUserId())) {
//                    if (dto.getApprovalUserId().equals("1")) {
//                        dto.setApprovalUserName("平台管理员");
//                    }
//                }
//            }
//            /*******************打桩代码**************************/
        }

        // 设置枚举类型
        for (ApprovalDTO dto : dtoList) {
            if (dto.getState() != null) {
                dto.setStateName(ApprovalState.getDescByCode(dto.getState()));
            }
            if (dto.getType() != null) {
                dto.setTypeName(ApprovalType.getDescByCode(dto.getType()));
            }
            if (dto.getApprovalResultType() != null) {
                dto.setApprovalResultTypeName(ApprovalResultType.getDescByCode(dto.getApprovalResultType()));
            }
        }
    }
}
